.. role:: raw-html-m2r(raw)
:format: html
Registers
=========
Introduction
------------
| Creating registers in SpinalHDL is very different than in VHDL or Verilog.
| In Spinal, there are no process/always blocks. Registers are explicitly defined at declaration.
| This difference from traditional event driven HDL has a big impact:
* You can assign registers and wires in the same scope, meaning the code doesn't need to be split between process/always blocks
* It make things much more flexible (see :ref:`Functions ` )
Clocks and resets are handled separately, see the :ref:`Clock domain ` chapter for details.
Instantiation
-------------
There is 4 ways to instantiate a register:
.. list-table::
:header-rows: 1
:widths: 50 55
* - Syntax
- Description
* - Reg(type : Data)
- Register of the given type
* - RegInit(resetValue : Data)
- Register loaded with the given ``resetValue`` when a reset occurs
* - RegNext(nextValue : Data)
- Register that samples the given ``nextValue`` each cycle
* - RegNextWhen(nextValue : Data, cond : Bool)
- Register that samples the given ``nextValue`` when a condition occurs
Here is an example declaring some registers:
.. code-block:: scala
//UInt register of 4 bits
val reg1 = Reg(UInt(4 bit))
//Register that samples reg1 each cycle
val reg2 = RegNext(reg1 + 1)
//UInt register of 4 bits initialized with 0 when the reset occurs
val reg3 = RegInit(U"0000")
reg3 := reg2
when(reg2 === 5){
reg3 := 0xF
}
//Register that samples reg3 when cond is True
val reg4 = RegNextWhen(reg3,cond)
The code above will infer the following logic:
.. image:: /asset/picture/register.svg
:align: center
.. note::
| The reg3 example shows how you can assign the value of a RegInit register. But it's possible to use the same syntax to assign to the other register types as well (Reg,RegNext,RegNextWhen).
| Just like in combinatorial assignments, the rule is 'Last assignment wins', but if no assignment is done, the register keeps its value.
Also, RegNext is an abstraction which is built over the Reg syntax. The two following sequences of code are strictly equivalent:
.. code-block:: scala
//Standard way
val something = Bool
val value = Reg(Bool)
value := something
//Short way
val something = Bool
val value = RegNext(something)
Reset value
-----------
In addition to the ``RegInit(value : Data)`` syntax which directly creates the register with a reset value,
you can also set the reset value by calling the ``init(value : Data)`` function on the register.
.. code-block:: scala
//UInt register of 4 bits initialized with 0 when the reset occur
val reg1 = Reg(UInt(4 bit)) init(0)
If you have a register containing a Bundle, you can use the ``init`` function on each element of the Bundle.
.. code-block:: scala
case class ValidRGB() extends Bundle{
val valid = Bool
val r,g,b = UInt(8 bits)
}
val reg = Reg(ValidRGB())
reg.valid init(False) //Only the valid of that register bundle will have an reset value.
Initialization value for simulation purposes
--------------------------------------------
For registers that don't need a reset value in RTL, but need an initialization value for simulation (to avoid x-propagation), you can ask for an random initialization value by calling the ``randBoot()`` function.
.. code-block:: scala
// UInt register of 4 bits initialized with a random value
val reg1 = Reg(UInt(4 bit)) randBoot()